﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using ParallelRuntimeLibrary.Internal;

namespace ParallelRuntimeLibrary
{
    public static class TaskManager
    {// This class will merge with Task class.

        private static WSScheduler mScheduler;
        private static object SyncObject = new object();

        internal static WSScheduler Scheduler
        {
            get 
            {
                if (mScheduler == null)
                {
                    lock (SyncObject)
                    {
                        if (mScheduler == null) mScheduler = new WSScheduler();
                    }
                }
                return mScheduler;
            }
        }

        /*/////////////////////////////////////////////////////////////////////////////*/

        public static void Start(Task task)
        {
            Scheduler.PushTask(task, PushTaskOptions.None);
        }

        public static void Start(params Task[] tasks)
        {
            Scheduler.PushTask(tasks, PushTaskOptions.None);
        }

        public static void WaitAll(params Task[] tasks)
        {
            // 1. Push all except first one
            Scheduler.PushTask(tasks, PushTaskOptions.WaitAll);

            // 2. Create Wait Handel, and wait.
            WaitHandle[] waitHandel = new WaitHandle[tasks.Length];
            for (int i = 0; i < tasks.Length; i++)
                waitHandel[i] = tasks[i].FinishedEvent;

            // 3. Wait.
            WaitHandle.WaitAll(waitHandel);
        }

        public static void WaitAny(params Task[] tasks)
        {
            // 1. Push all except first one
            Scheduler.PushTask(tasks, PushTaskOptions.WaitAll);

            // 2. Create Wait Handel, and wait.
            WaitHandle[] waitHandel = new WaitHandle[tasks.Length];
            for (int i = 0; i < tasks.Length; i++)
                waitHandel[i] = tasks[i].FinishedEvent;

            WaitHandle.WaitAny(waitHandel);
        }

        public static void WaitFirst(params Task[] tasks)
        {
            // 1. Push all except first one
            Scheduler.PushTask(tasks, PushTaskOptions.WaitFirst);

            return;
        }

        /*/////////////////////////////////////////////////////////////////////////////*/

        public static void Abort(Task task)
        {
            Scheduler.AbortTask(task);
        }

    }
}
